import os
import sqlite3
from datetime import datetime
from .db_storage import DataUsage
from .db_supplementary import (get_filtration_tasks, 
                               make_default_datetime,
                               make_default_datetime_finish,
                               proceed_new_name_type_subtype,
                               proceed_insertion_type_subtype,
                               produce_message_text_description)
from config import (basic_value_task,
                    basic_id_types,
                    basic_id_subtypes,
                    basic_value_task_type,
                    basic_value_task_subtype,
                    basic_value_task_notification,
                    basic_id_types_non_rem,
                    basic_id_subtypes_non_rem,
                    GroupingTasksMenu,
                    TableNotification, 
                    TableTypeSubType, 
                    TableTaskNotification, 
                    TableTaskSubType, 
                    DataBaseTable,
                    TableTaskType,
                    TableType,
                    TableSubType,
                    TableTypeUser,
                    TableSubTypeUser,
                    TableUser,
                    TableTask,
                    TableUserSettings, 
                    TableTaskExpired,
                    TableTaskFinished,
                    TableTaskProccessing)


class DataOperations(DataUsage):
    """
    class which is full used for the operations of the database
    """
    def __init__(self) -> None:
        super().__init__()
        self.acceptable_proccessing = [0, 1]
        self.acceptable_expired = [0, 2]
        self.acceptable_finished = [0, 3]
        self.list_name = [[1, 'Processing'], [2, 'Expired'], [3, 'Finished']]
        
    def check_presence_user_id(self, user_id:int) -> bool:
        """
        Method which is dedicated to develop boolean checking of the presence
        Input:  user_id = 
        Output: we developed boolean values to search it
        """
        presence = [f[0] for f in self.cursor.execute(f"""
                SELECT {TableUser.id}
                FROM {DataBaseTable.table_user} 
                WHERE {TableUser.id}=?;""", (user_id,))]
        return True if presence else False
        
    def insert_values_user(self, message_id, user_id, user_name_first, user_name_last, user_username) -> None:
        """
        Method which is dedicated to produce the insertion user values
        Input:  message_id = id of the selected message in the textin with the bot
                user_id = user id from the Telegram
                user_name_first = user name first from the Telegram
                user_lame_last = user name last from the Telegram
                user_username = username from the Telegram
        Output: we developed values of the 
        """
        if self.check_presence_user_id(user_id):
            return
        self.cursor.execute(f"""
            INSERT INTO {DataBaseTable.table_user}(
                {TableUser.id}, 
                {TableUser.name_first}, 
                {TableUser.name_last}, 
                {TableUser.username})
            VAlUES (?, ?, ?, ?);
        """, (user_id, user_name_first, user_name_last, user_username))
        self.connection.commit()
        self.insert_values_default_types_subtypes(user_id)
        self.insert_values_user_settings_basic(user_id)
        self.insert_values_default_tasks(user_id, message_id)
    
    def insert_values_user_subtype(self, user_id:int, user_text:str) -> str:
        """
        Method which is dedicated to insert users new subtype
        Input:  user_id = id of the user
                user_text = text which would be added new
        Output: we inserted to selected user values of the subtype
        """
        value_inserted_subtypes = self.cursor.execute(f"""
            SELECT {DataBaseTable.table_subtype}.{TableSubType.name}
            FROM {DataBaseTable.table_subtype_user}
            LEFT JOIN {DataBaseTable.table_subtype}
            ON {
                DataBaseTable.table_subtype_user}.{
                    TableSubTypeUser.id_subtype}={
                        DataBaseTable.table_subtype}.{
                            TableSubType.id}
            WHERE {DataBaseTable.table_subtype_user}.{TableSubTypeUser.id_user}=?;
            """, (user_id,)).fetchall()

        user_text = proceed_new_name_type_subtype(
            [f[0] for f in value_inserted_subtypes], 
            user_text)

        value_index_new = self.cursor.execute(f"""
            SELECT MAX({TableSubType.id})
            FROM {DataBaseTable.table_subtype} 
            LIMIT 1;
            """).fetchone()[0] + 1

        self.cursor.execute(f"""
            INSERT INTO {DataBaseTable.table_subtype}(
                {TableSubType.id},
                {TableSubType.name}
            )
            VALUES (?, ?);
            """, (value_index_new, user_text))

        self.cursor.execute(f"""
            INSERT INTO {DataBaseTable.table_subtype_user}(
                {TableSubTypeUser.id_subtype},
                {TableSubTypeUser.id_user}
            )
            VALUES (?, ?);
            """, (value_index_new, user_id))

        value_type = self.cursor.execute(f"""
            SELECT {TableTypeUser.id_type}
            FROM {DataBaseTable.table_type_user}
            WHERE {TableTypeUser.id_user}=?;
            """, (user_id, )).fetchall()
        self.cursor.executemany(f"""
            INSERT INTO {DataBaseTable.table_type_subtype}(
                {TableTypeSubType.id_type},
                {TableTypeSubType.id_subtype}
            )
            VALUES (?, ?);
            """, [(f[0], value_index_new) for f in value_type])

        self.connection.commit()
        return user_text

    def insert_values_user_type(self, user_id:int, user_text:str) -> str:
        """
        Method which is dedicated to insert new type for the values
        Input:  user_id = id of the selected user
                user_text = text value which would be added
        Output: we inserted values of the id
        """
        value_inserted_types = self.cursor.execute(f"""
            SELECT {DataBaseTable.table_type}.{TableType.name}
            FROM {DataBaseTable.table_type_user}
            LEFT JOIN {DataBaseTable.table_type}
            ON {
                DataBaseTable.table_type_user}.{
                    TableTypeUser.id_type}={
                        DataBaseTable.table_type}.{
                            TableType.id}
            WHERE {DataBaseTable.table_type_user}.{TableTypeUser.id_user}=?;
        """, (user_id,)).fetchall()
        
        user_text = proceed_new_name_type_subtype(
            [f[0] for f in value_inserted_types], 
            user_text)
        
        value_index_new = self.cursor.execute(f"""
            SELECT MAX({TableType.id})
            FROM {DataBaseTable.table_type} 
            LIMIT 1;
        """).fetchone()[0] + 1
        
        self.cursor.execute(f"""
            INSERT INTO {DataBaseTable.table_type}(
                {TableType.id},
                {TableType.name}
            )
            VALUES (?, ?);
        """, (value_index_new, user_text))
        
        self.cursor.execute(f"""
            INSERT INTO {DataBaseTable.table_type_user}(
                {TableTypeUser.id_type},
                {TableTypeUser.id_user}
            )
            VALUES (?, ?);
        """, (value_index_new, user_id))
        
        value_subtype = self.cursor.execute(f"""
            SELECT {TableSubTypeUser.id_subtype}
            FROM {DataBaseTable.table_subtype_user}
            WHERE {TableSubTypeUser.id_user}=?;
        """, (user_id, )).fetchall()
        
        self.cursor.executemany(f"""
            INSERT INTO {DataBaseTable.table_type_subtype}(
                {TableTypeSubType.id_subtype},
                {TableTypeSubType.id_type}
            )
            VALUES (?, ?);
        """, [(f[0], value_index_new) for f in value_subtype])
        self.connection.commit()
        return user_text

    def update_task_description_start(self, id_task:int, id_user:int, text:str) -> None:
        """
        Method which is dedicated to develop the update description of the task to it
        Input:  id_task = id of the selected task
                id_user = id of the selected user
                text = text which would be updated 
        """
        self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_task}
            SET {TableTask.description_start}=?
            WHERE {TableTask.id}=?
            AND {TableTask.id_user}=?
        """, (text, id_task, id_user))
        self.connection.commit()

    def update_task_description_finish(self, id_task:int, id_user:int, text:str) -> None:
        """
        Method which is dedicated to develop the update description of the task to it
        Input:  id_task = id of the selected task
                id_user = id of the selected user
                text = text which would be updated 
        """
        self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_task}
            SET {TableTask.description_finish}=?
            WHERE {TableTask.id}=?
            AND {TableTask.id_user}=?
        """, (text, id_task, id_user))
        self.connection.commit()

    def insert_values_user_settings_basic(self, user_id:int) -> None:
        """
        Method which is dedicated to return values of the settings of the users
        Input:  user_id = id of the user which created the profile within the system
        Output: we developed values of the 
        """
        self.cursor.execute(f"""
            INSERT INTO {DataBaseTable.table_user_settings}(
                {TableUserSettings.id_user}
            )
            VALUES (?);
        """, (user_id,))
        self.connection.commit()

    def insert_values_default_types_subtypes(self, user_id:int) -> None:
        """
        Method which is dedicated to develop values of the basics to the every basic values
        Input:  user_id = id of the user which is needed to get its values
        Output: we created all required values to get simple tasks
        """
        value_type, value_subtype, _ = proceed_insertion_type_subtype()
        value_type = [[i, user_id] for i, _ in value_type]
        value_subtype = [[i, user_id] for i, _ in value_subtype]
        self.cursor.executemany(f"""
            INSERT INTO {DataBaseTable.table_type_user}(
                {TableTypeUser.id_type}, 
                {TableTypeUser.id_user}) 
            VALUES (?, ?);""", value_type)
        self.cursor.executemany(f"""
            INSERT INTO {DataBaseTable.table_subtype_user}(
                {TableSubTypeUser.id_subtype}, 
                {TableSubTypeUser.id_user}) 
            VALUES (?, ?);""", value_subtype)
        self.connection.commit()

    def update_values_task_notification(self, id_task:int, id_not:int, id_not_new:int) -> None:
        """
        Method which is dedicated to change time of the notification
        Input:  id_task = id of the task which was previously used
                id_not = id of the notification to the user previous
                id_not_new = id of the notification to the user new
        Output: we changed the time of the task's notifications
        """
        if id_not == id_not_new:
            return
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_task_notification}
            WHERE {TableTaskNotification.id_task}=?
            AND {TableTaskNotification.id_notification}=?
        """, (id_task, id_not))
        self.cursor.execute(f"""
            INSERT INTO {DataBaseTable.table_task_notification}(
                {TableTaskNotification.id_task},
                {TableTaskNotification.id_notification}
            )
            VALUES (?,?)
        """, (id_task, id_not_new))
        self.connection.commit()
        
    def update_values_task_notification_datetime(self, id_task:int, id_user:int, id_type:int) -> None:
        """
        Method which is dedicated to update the time where to notify the user
        Input:  id_task = id of the selected task
                id_user = id of the selected user
                id_type = type of the datetime which is required to be changed
        Output: we updated values of the datetime
        """
        if id_type == 1:
            new_value = self.cursor.execute(f"""
            SELECT {TableTask.alarm_morning}
            FROM {DataBaseTable.table_task} 
            WHERE {TableTask.id}=? 
            AND {TableTask.id_user}=?""", (id_task, id_user)).fetchone()
            new_value = not bool(new_value[0]) if new_value else False
            self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_task}
            SET {TableTask.alarm_morning}=?
            WHERE {TableTask.id}=? 
            AND {TableTask.id_user}=?
            """, (new_value, id_task, id_user))

        elif id_type == 2:
            new_value = self.cursor.execute(f"""
            SELECT {TableTask.alarm_day}
            FROM {DataBaseTable.table_task} 
            WHERE {TableTask.id}=? 
            AND {TableTask.id_user}=?""", (id_task, id_user)).fetchone()
            new_value = not bool(new_value[0]) if new_value else False
            self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_task}
            SET {TableTask.alarm_day}=?
            WHERE {TableTask.id}=? 
            AND {TableTask.id_user}=?
            """, (new_value, id_task, id_user))

        elif id_type == 3:
            new_value = self.cursor.execute(f"""
            SELECT {TableTask.alarm_evening}
            FROM {DataBaseTable.table_task} 
            WHERE {TableTask.id}=? 
            AND {TableTask.id_user}=?""", (id_task, id_user)).fetchone()
            new_value = not bool(new_value[0]) if new_value else False
            self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_task}
            SET {TableTask.alarm_evening}=?
            WHERE {TableTask.id}=? 
            AND {TableTask.id_user}=?
            """, (new_value, id_task, id_user))

        if id_type in [1, 2, 3]:
            self.connection.commit()

    def update_task_datetime(self, id_task:int, id_user:int, time_delta:int) -> set:
        """
        Method which is dedicated to develop the values of the 
        Input:  id_task = id of the selected task
                id_user = id of the selected user
                time_delta = time delta which must be changed
        Output: we created the values of the new timing and return set of old and new date
        """
        print(self.cursor.execute(f"""
        
        """).fetchone())
        value_time = self.cursor.execute(f"""
            SELECT {TableTask.datetime_finish}
            FROM {DataBaseTable.table_task}
            WHERE {TableTask.id} = ?
            AND {TableTask.id_user}=?;
            """,(id_task, id_user)).fetchone()[0]
        value_time = datetime.strptime(value_time, "%Y-%m-%d %H:%M:%S.%f")
        value_time_new = make_default_datetime_finish(time_delta, value_time)
        self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_task}
            SET {TableTask.datetime_finish} = ?
            WHERE {TableTask.id} = ?
            AND {TableTask.id_user}=?;
            """, (
                value_time_new, 
                id_task, 
                id_user))
        self.connection.commit()
        return datetime.strftime(value_time, "%Y-%m-%d"), \
            datetime.strftime(value_time_new, "%Y-%m-%d")

    def return_info_task(self, id_task:int, id_user:int, id_accept:int) -> str:
        """
        Method which is dedicated to return all possible info about the tasks
        Input:  id_task = id of the selected task
                id_user = id of the user which is uses
                id_accept = id of the accepted values for it
        Output: string values for the returning messages
        """
        if id_accept in self.acceptable_proccessing:
            if not self.cursor.execute(f"""
                    SELECT * 
                    FROM {DataBaseTable.table_task_processing} 
                    WHERE {TableTaskProccessing.id}=? 
                    AND {TableTaskProccessing.id_user}=?""", 
                    (id_task, id_user)).fetchone():
                return GroupingTasksMenu.expired_tast_desc_processing, 0
            value_results = self.cursor.execute(f"""
                SELECT {DataBaseTable.table_task}.{TableTask.id},
                        {DataBaseTable.table_task}.{TableTask.id_message},
                        {DataBaseTable.table_task}.{TableTask.datetime_start},
                        {DataBaseTable.table_task}.{TableTask.datetime_finish},
                        {DataBaseTable.table_task}.{TableTask.description_start},
                        {DataBaseTable.table_type}.{TableType.name},
                        {DataBaseTable.table_subtype}.{TableSubType.name}
                FROM {DataBaseTable.table_task}
                INNER JOIN {DataBaseTable.table_task_type} 
                    ON {
                        DataBaseTable.table_task}.{
                            TableTask.id}=={
                                DataBaseTable.table_task_type}.{
                                    TableTaskType.id_task}
                INNER JOIN {DataBaseTable.table_type}
                    ON {
                        DataBaseTable.table_task_type}.{
                            TableTaskType.id_type}=={
                                DataBaseTable.table_type}.{
                                    TableType.id}
                INNER JOIN {DataBaseTable.table_task_subtype}
                    ON {
                        DataBaseTable.table_task}.{
                            TableTask.id}=={
                                DataBaseTable.table_task_subtype}.{
                                    TableTaskSubType.id_task}
                INNER JOIN {DataBaseTable.table_subtype}
                    ON {
                        DataBaseTable.table_task_subtype}.{
                            TableTaskSubType.id_subtype}=={
                                DataBaseTable.table_subtype}.{
                                    TableSubType.id}
                WHERE {DataBaseTable.table_task}.{TableTask.id}=?
                AND {DataBaseTable.table_task}.{TableTask.id_user}=?;""", 
            (id_task, id_user)).fetchone()

        if id_accept in self.acceptable_expired:
            if not self.cursor.execute(f"""
                    SELECT * 
                    FROM {DataBaseTable.table_task_expired} 
                    WHERE {TableTaskExpired.id}=? 
                    AND {TableTaskExpired.id_user}=?""", 
                    (id_task, id_user)).fetchone():
                return GroupingTasksMenu.expired_tast_desc_expired, 0
            value_results = self.cursor.execute(f"""
                SELECT {DataBaseTable.table_task}.{TableTask.id},
                        {DataBaseTable.table_task}.{TableTask.id_message},
                        {DataBaseTable.table_task}.{TableTask.datetime_start},
                        {DataBaseTable.table_task}.{TableTask.datetime_finish},
                        {DataBaseTable.table_task}.{TableTask.description_start},
                        {DataBaseTable.table_type}.{TableType.name},
                        {DataBaseTable.table_subtype}.{TableSubType.name}
                FROM {DataBaseTable.table_task}
                INNER JOIN {DataBaseTable.table_task_type} 
                    ON {
                        DataBaseTable.table_task}.{
                            TableTask.id}=={
                                DataBaseTable.table_task_type}.{
                                    TableTaskType.id_task}
                INNER JOIN {DataBaseTable.table_type}
                    ON {
                        DataBaseTable.table_task_type}.{
                            TableTaskType.id_type}=={
                                DataBaseTable.table_type}.{
                                    TableType.id}
                INNER JOIN {DataBaseTable.table_task_subtype}
                    ON {
                        DataBaseTable.table_task}.{
                            TableTask.id}=={
                                DataBaseTable.table_task_subtype}.{
                                    TableTaskSubType.id_task}
                INNER JOIN {DataBaseTable.table_subtype}
                    ON {
                        DataBaseTable.table_task_subtype}.{
                            TableTaskSubType.id_subtype}=={
                                DataBaseTable.table_subtype}.{
                                    TableSubType.id}
                WHERE {DataBaseTable.table_task}.{TableTask.id}=?
                AND {DataBaseTable.table_task}.{TableTask.id_user}=?;""", 
            (id_task, id_user)).fetchone()

        if id_accept in self.acceptable_finished:
            if not self.cursor.execute(f"""
                    SELECT * 
                    FROM {DataBaseTable.table_task_finished} 
                    WHERE {TableTaskFinished.id}=? 
                    AND {TableTaskFinished.id_user}=?""", 
                    (id_task, id_user)).fetchone():
                return GroupingTasksMenu.expired_tast_desc_finished, 0
            value_results = self.cursor.execute(f"""
                SELECT {DataBaseTable.table_task}.{TableTask.id},
                        {DataBaseTable.table_task}.{TableTask.id_message},
                        {DataBaseTable.table_task}.{TableTask.datetime_start},
                        {DataBaseTable.table_task}.{TableTask.datetime_finish},
                        {DataBaseTable.table_task}.{TableTask.description_start},
                        {DataBaseTable.table_task}.{TableTask.description_finish},
                        {DataBaseTable.table_type}.{TableType.name},
                        {DataBaseTable.table_subtype}.{TableSubType.name}
                FROM {DataBaseTable.table_task}
                INNER JOIN {DataBaseTable.table_task_type} 
                    ON {
                        DataBaseTable.table_task}.{
                            TableTask.id}=={
                                DataBaseTable.table_task_type}.{
                                    TableTaskType.id_task}
                INNER JOIN {DataBaseTable.table_type}
                    ON {
                        DataBaseTable.table_task_type}.{
                            TableTaskType.id_type}=={
                                DataBaseTable.table_type}.{
                                    TableType.id}
                INNER JOIN {DataBaseTable.table_task_subtype}
                    ON {
                        DataBaseTable.table_task}.{
                            TableTask.id}=={
                                DataBaseTable.table_task_subtype}.{
                                    TableTaskSubType.id_task}
                INNER JOIN {DataBaseTable.table_subtype}
                    ON {
                        DataBaseTable.table_task_subtype}.{
                            TableTaskSubType.id_subtype}=={
                                DataBaseTable.table_subtype}.{
                                    TableSubType.id}
                WHERE {DataBaseTable.table_task}.{TableTask.id}=?
                AND {DataBaseTable.table_task}.{TableTask.id_user}=?;""", 
            (id_task, id_user)).fetchone()
        return produce_message_text_description(value_results, id_accept)

    def return_info_settings(self, id_user:int) -> list:
        """
        Method which is dedicated to return values of the settings
        Input:  id_user = id of the selected user for the settings
        Output: we developed list of the settings
        """
        return self.cursor.execute(f"""
            SELECT {DataBaseTable.table_user_settings}.{TableUserSettings.default_by_types},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.default_by_subtypes},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.default_by_tasks},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.show_processing},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.show_expired},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.show_finished},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.add_timing},
                    {DataBaseTable.table_notification}.{TableNotification.id},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.default_change_morning},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.default_change_day},
                    {DataBaseTable.table_user_settings}.{TableUserSettings.default_change_evening}
            FROM {DataBaseTable.table_user_settings}
            INNER JOIN {DataBaseTable.table_notification}
            ON {
                DataBaseTable.table_user_settings}.{
                    TableUserSettings.default_frequency}={
                        DataBaseTable.table_notification}.{
                            TableNotification.id}
            WHERE {TableUserSettings.id_user}=?;
        """, (id_user,)).fetchone()

    def update_default_frequency(self, id_user:int, id_frequency:int) -> list:
        """
        Method which is dedicated to update the frequency of the default tasks
        Input:  id_user = id of selected user
                id_frequency = id of the selected frequency
        Output: we updated frequency of the user 
        """
        self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_user_settings}
            SET {TableUserSettings.default_frequency}=?
            WHERE {TableUserSettings.id_user}=?;
            """
        , (id_frequency, id_user))
        self.connection.commit()

    def update_default_grouping(self, id_user:int, id_type:int) -> None:
        """
        Method which is dedicated to update grouping of the
        Input:  id_user = id of the selected user
                id_type = if of the selected type for showings
        Output: we updated grouping tasks showings 
        """
        if id_type == 1:
            def_types, def_subtypes, def_tasks = True, False, False
        elif id_type == 2:
            def_types, def_subtypes, def_tasks = False, True, False
        elif id_type == 3:
            def_types, def_subtypes, def_tasks = False, False, True
        elif id_type == 4:
            def_types, def_subtypes, def_tasks = False, False, False
        self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_user_settings}
            SET {TableUserSettings.default_by_types}=?,
                {TableUserSettings.default_by_subtypes}=?,
                {TableUserSettings.default_by_tasks}=?
            WHERE {TableUserSettings.id_user}=?;
        """, (def_types, def_subtypes, def_tasks, id_user))
        self.connection.commit()

    def update_default_tasks_datetime(self, id_user:int, value_type:int, value_bool:bool) -> None:
        """
        Method which is dedicated to update datetime where to notify by tasks
        Input:  id_user = id of the user
                value_type = type of the datetime which is going to change
                value_bool = boolean values which 
        Output: we updated values of the datetime showings
        """
        if value_type == 1:
            self.cursor.execute(f"""
                UPDATE {DataBaseTable.table_user_settings}
                SET {TableUserSettings.default_change_morning}=?
                WHERE {TableUserSettings.id_user}=?
            """, (value_bool, id_user))
        elif value_type == 2:
            self.cursor.execute(f"""
                UPDATE {DataBaseTable.table_user_settings}
                SET {TableUserSettings.default_change_day}=?
                WHERE {TableUserSettings.id_user}=?
            """, (value_bool, id_user))
        elif value_type == 3:
            self.cursor.execute(f"""
                UPDATE {DataBaseTable.table_user_settings}
                SET {TableUserSettings.default_change_evening}=?
                WHERE {TableUserSettings.id_user}=?
            """, (value_bool, id_user))
        self.connection.commit()

    def update_default_tasks_showings(self, id_user:int, value_type:int, value_bool:bool) -> None:
        """
        Method which is dedicated to update the settings of the showings tasks
        Input:  id_user = id of the user
                value_type = type of the value which values to update
                value_bool = value which is about to updated values
        Output: we updated values of the showings of the tasks
        """
        if value_type == 1:
            self.cursor.execute(f"""
                UPDATE {DataBaseTable.table_user_settings}
                SET {TableUserSettings.show_processing}=?
                WHERE {TableUserSettings.id_user}=?
            """, (value_bool, id_user))
        elif value_type == 2:
            self.cursor.execute(f"""
                UPDATE {DataBaseTable.table_user_settings}
                SET {TableUserSettings.show_expired}=?
                WHERE {TableUserSettings.id_user}=?
            """, (value_bool, id_user))
        elif value_type == 3:
            self.cursor.execute(f"""
                UPDATE {DataBaseTable.table_user_settings}
                SET {TableUserSettings.show_finished}=?
                WHERE {TableUserSettings.id_user}=?
            """, (value_bool, id_user))
        self.connection.commit()

    def update_default_add_timing(self, number_new:int, id_user:int) -> None:
        """
        Method which is dedicated to change adding timings for the tasks and user settings
        Input:  number_new = number of days where to notify
                id_user = id of the selected user where to update
        Output: we updated the adding timings for it
        """
        self.cursor.execute(f"""
            UPDATE {DataBaseTable.table_user_settings}
            SET {TableUserSettings.add_timing} = ?
            WHERE {TableUserSettings.id_user} = ?;
        """, (number_new, id_user))
        self.connection.commit()

    def return_notifications_variations(self) -> list:
        """
        Method which is dedicated to return various values of the frequency notifications
        Input:  None
        Output: value lists of the notifications
        """
        return self.cursor.execute(f"""
            SELECT {TableNotification.id},
                    {TableNotification.type}
            FROM {DataBaseTable.table_notification};""").fetchall()

    def insert_values_task_processing(self, id_task:int, id_user:int) -> None:
        """
        Method which is dedicated to develop new processing tasks
        Input:  id_task = id of the task which is about insertion connection
                id_user = id of the user which is used
        Output: we successfully created new connection of the tasks
        """
        self.cursor.execute(f"""
            INSERT 
            INTO {DataBaseTable.table_task_processing}(
                {TableTaskProccessing.id}, 
                {TableTaskProccessing.id_user}, 
                {TableTaskProccessing.datetime})
            VALUES (?,?,?);
        """, (id_task, id_user, make_default_datetime()))
        self.connection.commit()

    def insert_values_task_expired(self, id_task:int, id_user:int) -> None:
        """
        Method which is dedicated to develop insert new expired tasks
        Input:  id_task = id of the task which is about insertion connection
                id_user = id of the user which is used
        Output: we successfully created new connection of the tasks
        """
        self.cursor.execute(f"""
            INSERT 
            INTO {DataBaseTable.table_task_expired}(
                {TableTaskExpired.id}, 
                {TableTaskExpired.id_user}, 
                {TableTaskExpired.datetime})
            VALUES (?,?,?);
        """, (id_task, id_user, make_default_datetime()))
        self.connection.commit()

    def insert_values_task_finished(self, id_task:int, id_user:int) -> None:
        """
        Method which is dedicated to develop insert new finished tasks
        Input:  id_task = id of the task which is about insertion connection
                id_user = id of the user which is used
        Output: we successfully created new connection of the tasks
        """
        self.cursor.execute(f"""
            INSERT 
            INTO {DataBaseTable.table_task_finished}(
                {TableTaskFinished.id}, 
                {TableTaskFinished.id_user}, 
                {TableTaskFinished.datetime})
            VALUES (?,?,?);
        """, (id_task, id_user, make_default_datetime()))
        self.connection.commit()

    def delete_values_task_processing(self, id_task:int, id_user:int) -> None:
        """
        Method which is dedicated to delete the connection of the processing tasks
        Input:  id_task = id of the task which is about insertion connection
                id_user = id of the user which is used
        Output: we successfully removed new connection of the tasks
        """
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_task_processing}
            WHERE {TableTaskProccessing.id}=?
            AND {TableTaskProccessing.id_user}=?;
        """, (id_task, id_user))
        self.connection.commit()

    def delete_values_task_finished(self, id_task:int, id_user:int) -> None:
        """
        Method which is dedicated to delete the connection of the finished tasks
        Input:  id_task = id of the task which is about insertion connection
                id_user = id of the user which is used
        Output: we successfully removed new connection of the tasks
        """
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_task_finished}
            WHERE {TableTaskFinished.id}=?
            AND {TableTaskFinished.id_user}=?;
        """, (id_task, id_user))
        self.connection.commit()

    def delete_values_task_expired(self, id_task:int, id_user:int) -> None:
        """
        Method which is dedicated to delete the connection of the finished tasks
        Input:  id_task = id of the task which is about insertion connection
                id_user = id of the user which is used
        Output: we successfully removed new connection of the tasks
        """
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_task_expired}
            WHERE {TableTaskExpired.id}=?
            AND {TableTaskExpired.id_user}=?;
        """, (id_task, id_user))
        self.connection.commit()

    def make_change_tasks_types(self, id_task:int, id_user:int, id_del:int=-1, id_ins:int=-1) -> None:
        """
        Method which is dedicated to change the type of the tasks from the values
        Input:  id_task = id of the selected tasks
                id_user = id of the selected user
                id_del = id of the deletion value
                id_ins = id of the insertion value
        Output: we made the values of the solutions
        """
        if id_del in self.acceptable_proccessing:
            self.delete_values_task_processing(id_task, id_user)
        if id_del in self.acceptable_expired:
            self.delete_values_task_expired(id_task, id_user)
        if id_del in self.acceptable_finished:
            self.delete_values_task_finished(id_task, id_user)
        
        if id_ins in self.acceptable_proccessing:
            self.insert_values_task_processing(id_task, id_user)
        if id_ins in self.acceptable_expired:
            self.insert_values_task_expired(id_task, id_user)
        if id_ins in self.acceptable_finished:
            self.insert_values_task_finished(id_task, id_user)
        

    def return_values_types_user(self, user_id:int) -> list:
        """
        Method which is dedicated to return values type of the user
        Input:  user_id = is of the selected user
        Output: we developed values to return of the selected user
        """
        return self.cursor.execute(f"""
            SELECT * 
            FROM {DataBaseTable.table_type}
            WHERE {TableType.id} IN (
                SELECT {TableTypeUser.id_type}
                FROM {DataBaseTable.table_type_user}
                WHERE {TableTypeUser.id_user}=?
            );
            """, (user_id,)).fetchall()

    def delete_user_type(self, id_user:int, id_type:int) -> None:
        """
        Method which is dedicated to delete connection of the user/type
        Input:  id_user = id of the user which want to delete this
                id_type = id of the type which is required to be removed
        Output: removed value of the connection of user/type
        """
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_type_user}
            WHERE {TableTypeUser.id_type}=? 
            AND {TableTypeUser.id_user}=?;
        """, (id_type, id_user))
        self.connection.commit()

    def delete_user_subtype(self, id_user:int, id_subtype:int) -> None:
        """
        Method which is dedicated to delete connection of the user/subtype
        Input:  id_user = id of the user which want to delete this
                id_subtype = id of the subtype which is required to be removed
        Output: removed value of the connection of user/subtype
        """
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_subtype_user}
            WHERE {TableSubTypeUser.id_subtype}=? 
            AND {TableSubTypeUser.id_user}=?;
        """, (id_subtype, id_user))
        self.connection.commit()

    def return_values_subtypes_user(self, user_id:int) -> list:
        """
        Method which is dedicated to return values subtype of the user
        Input:  user_id = id of selected user
        Output: we developed list of the returned sublists of selected user
        """
        return self.cursor.execute(f"""
            SELECT *
            FROM {DataBaseTable.table_subtype}
            WHERE {TableSubType.id} IN (
                SELECT {TableSubTypeUser.id_subtype}
                FROM {DataBaseTable.table_subtype_user}
                WHERE {TableSubTypeUser.id_user}=?
            );""", (user_id,)).fetchall()

    def return_values_type_description(self, user_id:int, type_id:int) -> set:
        """
        Method which is dedicated to get description of the type of selection user
        Input:  user_id = id of the user which requires this
                type_id = id the type which is required thos
        Output: developed values of the description values
        """
        type_main = self.cursor.execute(f"""
            SELECT * 
            FROM {DataBaseTable.table_type}
            WHERE {TableType.id}=?;""", 
            (type_id,)).fetchone()
        type_default = type_id in basic_id_types
        type_processing = self.cursor.execute(f"""
            SELECT COUNT({TableTaskProccessing.id})
            FROM {DataBaseTable.table_task_processing}
            WHERE {TableTaskProccessing.id} IN
                (SELECT {TableTaskType.id_task}
                FROM {DataBaseTable.table_task_type}
                WHERE {TableTaskType.id_type}=?) 
            AND {TableTaskProccessing.id} IN 
                (SELECT {TableTask.id}
                FROM {DataBaseTable.table_task}
                WHERE {TableTask.id_user}=?);
            """, (type_id, user_id)).fetchone()
        type_processing = type_processing[0]

        type_expired = self.cursor.execute(f"""
            SELECT COUNT({TableTaskExpired.id})
            FROM {DataBaseTable.table_task_expired}
            WHERE {TableTaskExpired.id} IN
                (SELECT {TableTaskType.id_task}
                FROM {DataBaseTable.table_task_type}
                WHERE {TableTaskType.id_type}=?) 
            AND {TableTaskExpired.id} IN (
                SELECT {TableTask.id}
                FROM {DataBaseTable.table_task}
                WHERE {TableTask.id_user}=?);
            """, (type_id, user_id)).fetchone()

        type_expired = type_expired[0]
        type_finished = self.cursor.execute(f"""
            SELECT COUNT({TableTaskFinished.id})
            FROM {DataBaseTable.table_task_finished}
            WHERE {TableTaskFinished.id} IN
                (SELECT {TableTaskType.id_task}
                FROM {DataBaseTable.table_task_type}
                WHERE {TableTaskType.id_type}=?) 
            AND {TableTaskFinished.id} IN (
                SELECT {TableTask.id}
                FROM {DataBaseTable.table_task}
                WHERE {TableTask.id_user}=?);
            """, (type_id, user_id)).fetchone()
        type_finished = type_finished[0]

        type_subtype = self.cursor.execute(f"""
            SELECT *
            FROM {DataBaseTable.table_subtype}
            WHERE {TableSubType.id} IN
                (SELECT {TableTypeSubType.id_subtype}
                FROM {DataBaseTable.table_type_subtype}
                WHERE {TableTypeSubType.id_type}=?);
            """, (type_id,)).fetchall()
        return type_main, type_default, type_processing, \
            type_expired, type_finished, type_subtype

    def return_values_subtype_description(self, user_id:int, subtype_id:int) -> set:
        """
        Method which is dedicated to get description of the subtype of slected user
        Input:  user_id = id of the selected users 
                subtype_id = id of the subtype which is dedicated
        Output: we developed all values for the description
        """
        subtype_main = self.cursor.execute(f"""
            SELECT * 
            FROM {DataBaseTable.table_subtype}
            WHERE {TableType.id}=?;""", 
            (subtype_id,)).fetchone()
        subtype_default = subtype_id in basic_id_subtypes
        subtype_processing = self.cursor.execute(f"""
            SELECT COUNT({TableTaskProccessing.id})
            FROM {DataBaseTable.table_task_processing}
            WHERE {TableTaskProccessing.id} IN
                (SELECT {TableTaskSubType.id_task}
                FROM {DataBaseTable.table_task_subtype}
                WHERE {TableTaskSubType.id_subtype}=?) 
            AND {TableTaskProccessing.id} IN 
                (SELECT {TableTask.id}
                FROM {DataBaseTable.table_task}
                WHERE {TableTask.id_user}=?);
            """, (subtype_id, user_id)).fetchone()
        subtype_processing = subtype_processing[0]

        subtype_expired = self.cursor.execute(f"""
            SELECT COUNT({TableTaskExpired.id})
            FROM {DataBaseTable.table_task_expired}
            WHERE {TableTaskExpired.id} IN
                (SELECT {TableTaskSubType.id_task}
                FROM {DataBaseTable.table_task_subtype}
                WHERE {TableTaskSubType.id_subtype}=?) 
            AND {TableTaskExpired.id} IN (
                SELECT {TableTask.id}
                FROM {DataBaseTable.table_task}
                WHERE {TableTask.id_user}=?);
            """, (subtype_id, user_id)).fetchone()
        subtype_expired = subtype_expired[0]

        subtype_finished = self.cursor.execute(f"""
            SELECT COUNT({TableTaskFinished.id})
            FROM {DataBaseTable.table_task_finished}
            WHERE {TableTaskFinished.id} IN
                (SELECT {TableTaskSubType.id_task}
                FROM {DataBaseTable.table_task_subtype}
                WHERE {TableTaskSubType.id_subtype}=?) 
            AND {TableTaskFinished.id} IN (
                SELECT {TableTask.id}
                FROM {DataBaseTable.table_task}
                WHERE {TableTask.id_user}=?);
            """, (subtype_id, user_id)).fetchone()
        subtype_finished = subtype_finished[0]

        subtype_type = self.cursor.execute(f"""
            SELECT *
            FROM {DataBaseTable.table_type}
            WHERE {TableType.id} IN
                (SELECT {TableTypeSubType.id_type}
                FROM {DataBaseTable.table_type_subtype}
                WHERE {TableTypeSubType.id_subtype}=?);
            """, (subtype_id,)).fetchall()
        return subtype_main, subtype_default, subtype_processing, \
            subtype_expired, subtype_finished, subtype_type

    def return_tasks_basic(self, user_id:int, sort_id:int=0, sort_check:bool=False) -> set:
        """
        Method which is dedicated to develop values of the tasks without anything except the sorting
        Input:  user_id = id of the selected user
                sort_id = id of the sorting values for the development
                sort_check = boolean value to check values of the settings
        Output: set of selected tasks which were previously used
        """
        value_tasks_processing, value_tasks_expired, value_tasks_finished = [], [], []

        if sort_check:
            b_proccessing, b_expired, b_finished = self.cursor.execute(f"""
                SELECT {TableUserSettings.show_processing},
                        {TableUserSettings.show_expired},
                        {TableUserSettings.show_finished}
                FROM {DataBaseTable.table_user_settings}
                WHERE {TableUserSettings.id_user}=?;
            """, (user_id,)).fetchone()
        else:
            b_proccessing, b_expired, b_finished = True, True, True

        if b_proccessing and sort_id in self.acceptable_proccessing:
            value_tasks_processing = self.cursor.execute(f"""
                SELECT 
                    DISTINCT({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                INNER JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskProccessing.id}
                    FROM {DataBaseTable.table_task_processing}
                    WHERE {TableTaskProccessing.id_user}=?);""", (user_id,)).fetchall()
        if b_expired and sort_id in self.acceptable_expired:
            value_tasks_expired = self.cursor.execute(f"""
                SELECT 
                    DISTINCT ({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                LEFT JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskExpired.id}
                    FROM {DataBaseTable.table_task_expired}
                    WHERE {TableTaskExpired.id_user}=?);
                """, (user_id, )).fetchall()
        if b_finished and sort_id in self.acceptable_finished:
            value_tasks_finished = self.cursor.execute(f"""
                SELECT DISTINCT({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                LEFT JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskFinished.id}
                    FROM {DataBaseTable.table_task_finished}
                    WHERE {TableTaskFinished.id_user}=?);
                """, (user_id, )).fetchall()
        return value_tasks_processing, value_tasks_expired, value_tasks_finished

    def return_tasks_by_subtypes(self, user_id:int, id_subtype:int, sort_id:int=0, sort_check:bool=False) -> set:
        """
        Method which is dedicated to develop values of the tasks based on the subtypes
        Input: user_id = id of the selected user
               id_subtype = id of the selected subtype
               sort_id = id of sorting values of the showings
               sort_check = boolean to check values of the settings
        Ouput: set of all dedicated tasks
        """
        value_tasks_processing, value_tasks_expired, value_tasks_finished = [], [], []

        if sort_check:
            b_proccessing, b_expired, b_finished = self.cursor.execute(f"""
                SELECT {TableUserSettings.show_processing},
                        {TableUserSettings.show_expired},
                        {TableUserSettings.show_finished}
                FROM {DataBaseTable.table_user_settings}
                WHERE {TableUserSettings.id_user}=?;
            """, (user_id,)).fetchone()
        else:
            b_proccessing, b_expired, b_finished = True, True, True

        if b_proccessing and sort_id in self.acceptable_proccessing:
            value_tasks_processing = self.cursor.execute(f"""
                SELECT 
                    DISTINCT({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                INNER JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskProccessing.id}
                    FROM {DataBaseTable.table_task_processing}
                    WHERE {TableTaskProccessing.id_user}=?) 
                AND {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskSubType.id_task} 
                    FROM {DataBaseTable.table_task_subtype}
                    WHERE {TableTaskSubType.id_subtype}=?);""", (user_id, id_subtype)).fetchall()

        if b_expired and sort_id in self.acceptable_expired:
            value_tasks_expired = self.cursor.execute(f"""
                SELECT 
                    DISTINCT ({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                LEFT JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskExpired.id}
                    FROM {DataBaseTable.table_task_expired}
                    WHERE {TableTaskExpired.id_user}=?) 
                AND {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskSubType.id_task} 
                    FROM {DataBaseTable.table_task_subtype}
                    WHERE {TableTaskSubType.id_subtype}=?);
                """, (user_id, id_subtype)).fetchall()

        if b_finished and sort_id in self.acceptable_finished:
            value_tasks_finished = self.cursor.execute(f"""
                SELECT DISTINCT({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                LEFT JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskFinished.id}
                    FROM {DataBaseTable.table_task_finished}
                    WHERE {TableTaskFinished.id_user}=?) 
                AND {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskSubType.id_task} 
                    FROM {DataBaseTable.table_task_subtype}
                    WHERE {TableTaskSubType.id_subtype}=?);
                """, (user_id, id_subtype)).fetchall()
        return value_tasks_processing, value_tasks_expired, value_tasks_finished

    def return_tasks_by_types(self, user_id:int, id_type:int, sort_id:int=0, sort_check:bool=False) -> set:
        """
        Method which is dedicated to develop values of the tasks based on the types
        Input:  user_id = id of the selected user
                id_type = id of the selected type
                sort_id = sorting of values to return
                sort_check = sort check of the returning values
        Output: we developed set of the values of tasks which were detected by types
        """
        value_tasks_processing, value_tasks_expired, value_tasks_finished = [], [], []
        if sort_check:
            b_proccessing, b_expired, b_finished = self.cursor.execute(f"""
                SELECT {TableUserSettings.show_processing},
                        {TableUserSettings.show_expired},
                        {TableUserSettings.show_finished}
                FROM {DataBaseTable.table_user_settings}
                WHERE {TableUserSettings.id_user}=?;
            """, (user_id,)).fetchone()
        else:
            b_proccessing, b_expired, b_finished = True, True, True

        if b_proccessing and sort_id in self.acceptable_proccessing:
            value_tasks_processing = self.cursor.execute(f"""
                SELECT DISTINCT({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                INNER JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskProccessing.id}
                    FROM {DataBaseTable.table_task_processing}
                    WHERE {TableTaskProccessing.id_user}=?) 
                AND {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskType.id_task} 
                    FROM {DataBaseTable.table_task_type}
                    WHERE {TableTaskType.id_type}=?);""", (user_id, id_type)).fetchall()

        if b_expired and sort_id in self.acceptable_expired:
            value_tasks_expired = self.cursor.execute(f"""
                SELECT DISTINCT ({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                LEFT JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskExpired.id}
                    FROM {DataBaseTable.table_task_expired}
                    WHERE {TableTaskExpired.id_user}=?) 
                AND {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskType.id_task} 
                    FROM {DataBaseTable.table_task_type}
                    WHERE {TableTaskType.id_type}=?);
                """, (user_id, id_type)).fetchall()

        if b_finished and sort_id in self.acceptable_finished:
            value_tasks_finished = self.cursor.execute(f"""
                SELECT DISTINCT({DataBaseTable.table_task}.{TableTask.id}),
                    {DataBaseTable.table_task}.{TableTask.id_user_task},
                    {DataBaseTable.table_task}.{TableTask.alarm_morning},
                    {DataBaseTable.table_task}.{TableTask.alarm_day},
                    {DataBaseTable.table_task}.{TableTask.alarm_evening},
                    {DataBaseTable.table_notification}.{TableNotification.type},
                    {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}
                FROM {DataBaseTable.table_task}, 
                    {DataBaseTable.table_notification}
                    {DataBaseTable.table_task_notification}
                INNER JOIN {DataBaseTable.table_task_notification} ON 
                    {DataBaseTable.table_task}.{
                            TableTask.id
                            }=={
                                DataBaseTable.table_task_notification
                                }.{
                                    TableTaskNotification.id_task
                                    }
                LEFT JOIN {DataBaseTable.table_notification} ON
                    {
                        DataBaseTable.table_task_notification
                    }.{
                        TableTaskNotification.id_notification
                        }=={
                            DataBaseTable.table_notification
                            }.{
                                TableNotification.id
                                }
                WHERE {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskFinished.id}
                    FROM {DataBaseTable.table_task_finished}
                    WHERE {TableTaskFinished.id_user}=?) 
                AND {DataBaseTable.table_task}.{TableTask.id} IN (
                    SELECT {TableTaskType.id_task} 
                    FROM {DataBaseTable.table_task_type}
                    WHERE {TableTaskType.id_type}=?);
                """, (user_id, id_type)).fetchall()
        return value_tasks_processing, value_tasks_expired, value_tasks_finished
        
    def insert_values_default_tasks(self, user_id:int, message_id:int, basic_insertion:bool=True) -> None:
        """
        Method which is dedicated to develop basic task for the user
        Input:  user_id = id of the selected user
                message_id = id of the message in the dialog
        Output: we created values of default tasks to the values
        """
        datetime_now = datetime.now()
        if basic_insertion:
            task_user_id, task_description, task_notice_morning, \
            task_notice_day, task_notice_evening = basic_value_task
            notification = basic_value_task_notification
        else:
            task_description = ''
            task_notice_morning, task_notice_day, \
            task_notice_evening, notification, task_user_id = self.cursor.execute(f"""
                SELECT {DataBaseTable.table_user_settings}.{TableUserSettings.default_change_morning},
                        {DataBaseTable.table_user_settings}.{TableUserSettings.default_change_day},
                        {DataBaseTable.table_user_settings}.{TableUserSettings.default_change_evening},
                        {DataBaseTable.table_user_settings}.{TableUserSettings.default_frequency},
                        MAX({DataBaseTable.table_task}.{TableTask.id_user_task}) + 1
                FROM {DataBaseTable.table_user_settings}
                INNER JOIN {DataBaseTable.table_task}
                ON {
                    DataBaseTable.table_user_settings}.{
                        TableUserSettings.id_user}=={
                            DataBaseTable.table_task}.{
                                TableTask.id_user}
                WHERE {DataBaseTable.table_user_settings}.{TableUserSettings.id_user}=?;""", (user_id,)).fetchone()
        self.cursor.execute(f"""
            INSERT INTO {DataBaseTable.table_task}(
                {TableTask.id_message}, 
                {TableTask.id_user},
                {TableTask.id_user_task},
                {TableTask.description_start},
                {TableTask.datetime_start},
                {TableTask.datetime_finish},
                {TableTask.alarm_morning},
                {TableTask.alarm_day},
                {TableTask.alarm_evening})
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);""", 
            (message_id, user_id, task_user_id, task_description, 
            datetime_now, make_default_datetime_finish(), 
            task_notice_morning, task_notice_day, task_notice_evening))
        task_id = self.cursor.execute(f"""
            SELECT {TableTask.id} 
            FROM {DataBaseTable.table_task} 
            WHERE {TableTask.id_message} = ?;""", (message_id,)).fetchone()
        task_id = task_id[-1] if task_id else False
        if task_id:
            self.cursor.execute(f"""
                INSERT INTO {DataBaseTable.table_task_processing}(
                    {TableTaskProccessing.id},
                    {TableTaskProccessing.id_user},
                    {TableTaskProccessing.datetime})
                VALUES (?, ?, ?);""", (task_id, user_id, datetime_now))
            self.cursor.execute(f"""
                INSERT INTO {DataBaseTable.table_task_type}(
                    {TableTaskType.id_task}, 
                    {TableTaskType.id_type})
                VALUES (?, ?);""", (task_id, basic_value_task_type))
            self.cursor.execute(f"""
                INSERT INTO {DataBaseTable.table_task_subtype}(
                    {TableTaskSubType.id_task},
                    {TableTaskSubType.id_subtype})
                VALUES (?, ?);""", (task_id, basic_value_task_subtype))
            self.cursor.execute(f"""
                INSERT INTO {DataBaseTable.table_task_notification}(
                    {TableTaskNotification.id_task},
                    {TableTaskNotification.id_notification})
                VALUES (?, ?);""", (task_id, notification))
        self.connection.commit()

    def return_values_tasks(self, value_id:int, value_type_return:int=0) -> set:
        """
        Method which is dedicated to develop values of the tasks of the users
        Input:  value_id = id of the user
                value_type_return = type of the returnal of all of this values
        Output: we developed values of the tasks, divided by different values
        """
        task_expired = []
        task_finished = []
        task_processing = []

        value_task = self.cursor.execute(f"""
            SELECT * 
            FROM {DataBaseTable.table_task} 
            WHERE {TableTask.id_user}=?;""", 
            (value_id,)).fetchall()
        
        if value_type_return in self.acceptable_proccessing:
            value_task_processing = self.cursor.execute(f"""
                SELECT {TableTaskProccessing.id} 
                FROM {DataBaseTable.table_task_processing} 
                WHERE {TableTaskProccessing.id_user}=?;""",
                (value_id,)).fetchall()
        
        if value_type_return in self.acceptable_expired:
            value_task_expired = self.cursor.execute(f"""
                SELECT {TableTaskExpired.id} 
                FROM {DataBaseTable.table_task_expired} 
                WHERE {TableTaskExpired.id_user}=?;""",
                (value_id,)).fetchall()
        
        if value_type_return in self.acceptable_finished:
            value_task_finished = self.cursor.execute(f"""
                SELECT {TableTaskFinished.id} 
                FROM {DataBaseTable.table_task_finished} 
                WHERE {TableTaskFinished.id_user}=?;""",
                (value_id,)).fetchall()
        if value_type_return in [1, 2]:
            task_processing = get_filtration_tasks(value_task, [f[0] for f in value_task_processing])
        if value_type_return in [1, 3]:
            task_expired = get_filtration_tasks(value_task, [f[0] for f in value_task_expired])
        if value_type_return in [1, 4]:
            task_finished = get_filtration_tasks(value_task, [f[0] for f in value_task_finished])
        return task_processing, task_expired, task_finished

    def return_values_tasks_menu(self, value_id:int) -> set:
        """
        Method which is dedicated to develop values of the tasks of the users for selected menu
        Input:  value_id = id of the user
        Output: we developed values of the tasks, divided by different values
        """
        task_processing = self.cursor.execute(f"""
            SELECT COUNT({TableTaskProccessing.id})
            FROM {DataBaseTable.table_task_processing}
            WHERE {TableTaskProccessing.id_user}=?""", (value_id,)).fetchone()
        task_processing = task_processing[0] if task_processing else 0
        task_expired = self.cursor.execute(f"""
            SELECT COUNT({TableTaskExpired.id})
            FROM {DataBaseTable.table_task_expired}
            WHERE {TableTaskExpired.id_user}=?""", (value_id,)).fetchone()
        task_expired = task_expired[0] if task_expired else 0
        task_finished = self.cursor.execute(f"""
            SELECT COUNT({TableTaskFinished.id})
            FROM {DataBaseTable.table_task_finished}
            WHERE {TableTaskFinished.id_user}=?""", (value_id,)).fetchone()
        task_finished = task_finished[0] if task_finished else 0
        value_list_id = [[n, q] for (n, _), q in zip(self.list_name, [task_processing, task_expired, task_finished])]
        return value_list_id, self.list_name

    def change_all_tasks_types(self, id_type:int, id_type_new:int=basic_id_types_non_rem[0]) -> None:
        """
        Method which is dedicated to change multiple tasks values
        Input:  id_type = id of the selected type
                id_type_new = id of the type which we are using and would be using
        Output: we moved all possible values to the unknown values 
        """
        id_tasks = self.cursor.execute(f"""
            SELECT {TableTaskType.id_task}
            FROM {DataBaseTable.table_task_type}
            WHERE {TableTaskType.id_type}=?;
        """, (id_type,)).fetchall()
        if not id_tasks:
            return
        id_tasks_old = [[id_type, id_task[0]] for id_task in id_tasks]
        self.cursor.executemany(f"""
            DELETE 
            FROM {DataBaseTable.table_task_type}
            WHERE {TableTaskType.id_type}=?
            AND {TableTaskType.id_task}=?
        """, id_tasks_old)
        id_tasks_new = [[id_type_new, id_task[0]] for id_task in id_tasks]
        self.cursor.executemany(f"""
            INSERT 
            INTO {DataBaseTable.table_task_type}(
                {TableTaskType.id_type},
                {TableTaskType.id_task}
                )
            VALUES (?, ?);""", id_tasks_new)
        self.connection.commit()

    def change_all_tasks_subtypes(self, id_subtype:int, id_subtype_new:int=basic_id_subtypes_non_rem[0]) -> None:
        """
        Method which is dedicated to change subtypes  
        Input:  id_subtype = id of the subtype which would be removed
                id_subtype_new = id of the subtype which we are using
        Output: we changed values of the subtypes
        """
        id_tasks = self.cursor.execute(f"""
            SELECT {TableTaskSubType.id_task}
            FROM {DataBaseTable.table_task_subtype}
            WHERE {TableTaskSubType.id_subtype}=?;
        """, (id_subtype,)).fetchall()
        if not id_tasks:
            return
        id_tasks_old = [[id_subtype, id_task[0]] for id_task in id_tasks]
        self.cursor.executemany(f"""
            DELETE 
            FROM {DataBaseTable.table_task_subtype}
            WHERE {TableTaskSubType.id_subtype}=?
            AND {TableTaskSubType.id_task}=?
        """, id_tasks_old)
        id_tasks_new = [[id_subtype_new, id_task[0]] for id_task in id_tasks]
        self.cursor.executemany(f"""
            INSERT 
            INTO {DataBaseTable.table_task_subtype}(
                {TableTaskSubType.id_subtype},
                {TableTaskSubType.id_task}
                )
            VALUES (?, ?);""", id_tasks_new)
        self.connection.commit()

    def remove_subtypes_types_by_user(self, id_type:int) -> None:
        """
        Method which is dedicated to change values of the type and subtypes
        Input:  id_type = id of the type which would be deleted
        Output: changed values of the removable type
        """
        id_subtypes = self.cursor.execute(f"""
            SELECT {TableTypeSubType.id_subtype}
            FROM {DataBaseTable.table_type_subtype}
            WHERE {TableTypeSubType.id_type}=?;
        """, (id_type,)).fetchall()
        if not id_subtypes:
            return
        id_types_old = [[id_type, id_subtype[0]] for id_subtype in id_subtypes]
        self.cursor.executemany(f"""
            DELETE 
            FROM {DataBaseTable.table_type_subtype}
            WHERE {TableTypeSubType.id_type}=?
            AND {TableTypeSubType.id_subtype}=?
        """, id_types_old)
        self.connection.commit()

    def remove_types_subtypes_by_user(self, id_subtype:int) -> None:
        """
        Method which is dedicated to change values of the types and subtypes
        Input:  id_subtype = id of the subtype which would be deleted
        Output: changed values of the removable subtype
        """
        id_types = self.cursor.execute(f"""
            SELECT {TableTypeSubType.id_type}
            FROM {DataBaseTable.table_type_subtype}
            WHERE {TableTypeSubType.id_subtype}=?;
        """, (id_subtype,)).fetchall()
        if not id_types:
            return
        id_types_old = [[id_subtype, id_type[0]] for id_type in id_types]
        self.cursor.executemany(f"""
            DELETE 
            FROM {DataBaseTable.table_type_subtype}
            WHERE {TableTypeSubType.id_subtype}=?
            AND {TableTypeSubType.id_type}=?
        """, id_types_old)
        self.connection.commit()

    def remove_types_removed_by_user(self, id_type:int) -> None:
        """
        Method which is dedicated to remove types from the database
        Input:  id_type = id of the selected type which would be removed
        Output: we removed values to develop the database lighter
        """
        if not id_type in basic_id_types:
            return
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_type}
            WHERE {TableType.id}=?;
        """, (id_type,))
        self.connection.commit()

    def remove_subtypes_removed_by_user(self, id_subtype:int) -> None:
        """
        Method which is dedicated to remove subtypes from the databases
        Input:  id_subtype = id of the selected subtype which will be removed
        Output: we removed values to develop the datatabase lighter
        """
        if not id_subtype in basic_id_subtypes:
            return
        self.cursor.execute(f"""
            DELETE
            FROM {DataBaseTable.table_subtype}
            WHERE {TableSubType.id}=?;
        """, (id_subtype,))
        self.connection.commit()

    def return_type_user_change(self, user_id:int) -> list:
        """
        Method which is dedicated to return all possible values
        Input:  user_id = user which need to change type
        Output: list of the selected types which user contains
        """
        return self.cursor.execute(f"""
            SELECT * 
            FROM {DataBaseTable.table_type}
            WHERE {TableType.id} 
            IN (
                SELECT {TableTypeUser.id_type} 
                FROM {DataBaseTable.table_type_user}
                WHERE {TableTypeUser.id_user} = ?
                );
        """, (user_id,)).fetchall()

    def return_subtype_user_change(self, user_id:int) -> list:
        """
        Method which is dedicated to return all values of the subtypes
        Input:  user_id = id of the selected user which would be further used
        Output: list of values which would be further used
        """
        return self.cursor.execute(f"""
            SELECT * 
            FROM {DataBaseTable.table_subtype}
            WHERE {TableSubType.id} 
            IN (
                SELECT {TableSubTypeUser.id_subtype} 
                FROM {DataBaseTable.table_subtype_user}
                WHERE {TableSubTypeUser.id_user} = ?
                );
        """, (user_id,)).fetchall()

    def return_type_task(self, task_id:int) -> int:
        """
        Method which is dedicated to return type id of the selected task
        Input:  task_id = id of the selected task
        Output: returned type of the task
        """
        return self.cursor.execute(f"""
            SELECT {TableTaskType.id_type}
            FROM {DataBaseTable.table_task_type}
            WHERE {TableTaskType.id_task} = ?;
        """, (task_id,)).fetchone()[0]

    def return_subtype_task(self, task_id:int) -> int:
        """
        Method which is dedicated to return subtypes of the task
        Input:  task_id = id of the selected task
        Output: id of the subtype of the task
        """
        return self.cursor.execute(f"""
            SELECT {TableTaskSubType.id_subtype}
            FROM {DataBaseTable.table_task_subtype}
            WHERE {TableTaskSubType.id_task} = ?;
        """, (task_id,)).fetchone()[0]

    def update_type_task(self, task_id:int, type_id:int, type_id_new:int) -> None:
        """
        Method which is dedicated to develop new type of tasks of it
        Input:  task_id = id of the selected task
                type_id = id of the selected type
                type_id_new = id of the new type
        Output: we developed new connection of if
        """
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_task_type}
            WHERE {TableTaskType.id_task}=?
            AND {TableTaskType.id_type}=?;""", 
            (task_id, type_id))
        self.cursor.execute(f"""
            INSERT 
            INTO {DataBaseTable.table_task_type}(
                {TableTaskType.id_task},
                {TableTaskType.id_type}
            )
            VALUES (?, ?);""", (task_id, type_id_new))
        self.connection.commit()

    def update_subtype_task(self, task_id:int, subtype_id:int, subtype_id_new:int) -> None:
        """
        Method which is dedicated to update the subtypes of the tasks
        Input:  task_id = id of selected task
                subtype_id = id of previous subtype
                subtype_id_new = id of new subtype
        Output: we removed and inserted new values of subtype of this task
        """
        self.cursor.execute(f"""
            DELETE 
            FROM {DataBaseTable.table_task_subtype}
            WHERE {TableTaskSubType.id_task}=?
            AND {TableTaskSubType.id_subtype}=?;""", 
            (task_id, subtype_id))
        self.cursor.execute(f"""
            INSERT 
            INTO {DataBaseTable.table_task_subtype}(
                {TableTaskSubType.id_task},
                {TableTaskSubType.id_subtype}
            )
            VALUES (?, ?);""", (task_id, subtype_id_new))
        self.connection.commit()

    def select_count_moving_tasks_type(self, id_user:int, id_type:int) -> int:
        """
        Method which is dedicated to select counting of the values
        Input:  id_user = id of the user for searching
                id_type = if of the type which is required
        Output: number of counted values for it
        """
        return self.cursor.execute(f"""
            SELECT COUNT({TableTaskType.id_task}) 
            FROM {DataBaseTable.table_task_type}
            WHERE {TableTaskType.id_type}=?
            AND {TableTaskType.id_type} 
                IN (
                    SELECT {TableTypeUser.id_type} 
                    FROM {DataBaseTable.table_type_user}
                    WHERE {TableTypeUser.id_user}=?
                );""", (id_type, id_user)).fetchone()[0]

    def select_count_moving_tasks_subtype(self, id_user:int, id_subtype:int) -> int:
        """
        Method which is dedicated to select counting of the values
        Input:  id_user = id of the selected user which was created
                id_subtype = id of the subtype which we are going to work with
        Output: number of counted tasks
        """
        return self.cursor.execute(f"""
            SELECT COUNT({TableTaskSubType.id_task}) 
            FROM {DataBaseTable.table_task_subtype}
            WHERE {TableTaskSubType.id_subtype}=?
            AND {TableTaskSubType.id_subtype} 
                IN (
                    SELECT {TableSubTypeUser.id_subtype} 
                    FROM {DataBaseTable.table_subtype_user}
                    WHERE {TableSubTypeUser.id_user}=?
                );""", (id_subtype, id_user)).fetchone()[0]

    def return_values_tasks_subgroup_menu(self, value_id:int) -> set:
        """
        Method which is dedicated to return values which were 
        Input:  value_id = id value of the user
        Output: we developed all possible values of the menu
        """
        value_subtypes_selected = self.cursor.execute(f"""
            SELECT * FROM 
            {DataBaseTable.table_subtype_user}
            WHERE {TableSubTypeUser.id_user}=?""", 
            (value_id,)).fetchall()
        value_subtypes_id = self.cursor.execute(f"""
            SELECT {TableTaskSubType.id_subtype}
            FROM {DataBaseTable.table_task_subtype}
            WHERE {TableTaskSubType.id_task} IN
            (
                SELECT {TableTask.id} 
                FROM {DataBaseTable.table_task}
                WHERE {TableTask.id_user}=?
            );""", 
            (value_id,)).fetchall()
        value_subtypes_id = [f[0] for f in value_subtypes_id]
        value_return = [[i, 0] for i, _ in value_subtypes_selected if i not in value_subtypes_id]
        value_return.extend([[i, value_subtypes_id.count(i)] for i in set(value_subtypes_id)])
        value_return = sorted(value_return, key = lambda x: x[0])
        return value_return, self.cursor.execute(f"""
            SELECT {TableSubType.id}, {TableSubType.name} 
            FROM {DataBaseTable.table_subtype}
            WHERE {TableSubType.id} 
            IN ({','.join('?' for _ in value_return)});
            """, [f for f, _ in value_return]).fetchall()

    def return_values_tasks_group_menu(self, value_id:int) -> set:
        """
        Method which is dedicated to return all values of 
        Input:  value_id = id of the user
        Output: we developed values of the user and groups 
        """
        value_types_selected = self.cursor.execute(f"""
            SELECT * FROM 
            {DataBaseTable.table_type_user}
            WHERE {TableTypeUser.id_user}=?""", 
            (value_id,)).fetchall()
        value_types_id = self.cursor.execute(f"""
            SELECT {TableTaskType.id_type}
            FROM {DataBaseTable.table_task_type}
            WHERE {TableTaskType.id_task} IN
            (
                SELECT {TableTask.id} 
                FROM {DataBaseTable.table_task}
                WHERE {TableTask.id_user}=?
            );""", 
            (value_id,)).fetchall()
        value_types_id = [f[0] for f in value_types_id]
        value_return = [[i, 0] for i, _ in value_types_selected if i not in value_types_id]
        value_return.extend([[i, value_types_id.count(i)] for i in set(value_types_id)])
        value_return = sorted(value_return, key = lambda x: x[0])
        return value_return, self.cursor.execute(f"""
            SELECT {TableType.id}, {TableType.name} 
            FROM {DataBaseTable.table_type}
            WHERE {TableSubType.id} 
            IN ({','.join('?' for _ in value_return)});
            """, [f for f, _ in value_return]).fetchall()
        
    def make_basic_statistics(self, id_user:int) -> set:
        """
        Method which is dedicated to develop user statistics
        Input:  id_user = id of the selected user
        Output: we developed values of the basic statistics
        """
        return self.cursor.execute(f"""
            SELECT COUNT({DataBaseTable.table_task_processing}.{TableTaskProccessing.id}),
                    {DataBaseTable.table_user}.{TableUser.datetime}
            FROM {DataBaseTable.table_user}
            LEFT JOIN {DataBaseTable.table_task_processing} 
                ON {
                    DataBaseTable.table_task_processing}.{
                        TableTaskProccessing.id_user}=={
                            DataBaseTable.table_user}.{
                                TableUser.id}
            WHERE {DataBaseTable.table_user}.{TableUser.id}=?;
        """, (id_user,)).fetchone(), \
        self.cursor.execute(f"""
            SELECT COUNT({TableTaskExpired.id})
            FROM {DataBaseTable.table_task_expired}
            WHERE {TableTaskExpired.id_user}=?;
        """, (id_user,)).fetchone()[0], \
        self.cursor.execute(f"""
            SELECT COUNT({TableTaskFinished.id})
            FROM {DataBaseTable.table_task_finished}
            WHERE {TableTaskFinished.id_user}=?;
        """, (id_user,)).fetchone()[0]

    def get_values_tasks_frequently(self, value_day_type:int, value_id_return:int) -> list:
        """
        Method which is dedicated to develop values of the tasks which we would after notify
        Input:  value_id_return = id of the selected Nitification values
        Output: we got tasks which would be notify after
        """
        if value_day_type == 1:
            searched = TableTask.alarm_morning
        if value_day_type == 2:
            searched == TableTask.alarm_day
        if value_day_type == 3:
            searched == TableTask.alarm_evening
        return self.cursor.execute(f"""
            {DataBaseTable.table_task}.{TableTask.id},
            {DataBaseTable.table_task}.{TableTask.datetime_start}
            FROM {DataBaseTable.table_task}
            LEFT JOIN {DataBaseTable.table_task_processing}
            ON {
                DataBaseTable.table_task}.{
                    TableTask.id}=={
                        DataBaseTable.table_task_processing}.{
                            TableTaskProccessing.id}
            LEFT JOIN {DataBaseTable.table_task_notification}
            ON {
                DataBaseTable.table_task}.{
                    TableTask.id}=={
                        DataBaseTable.table_task_notification}.{
                            TableTaskNotification.id_task}
            WHERE {DataBaseTable.table_task_notification}.{TableTaskNotification.id_notification}=?
            AND {DataBaseTable.table_task}.{searched}=True;
        """, (value_id_return,)).fetchall()

    def make_basic_testing(self) -> None:
        """
        Method which is dedicated to produce basic showing of the selected testing
        Input:  None
        Output: we created values of the testings
        """
        value_check_type = self.cursor.execute(f"""
            SELECT * FROM {DataBaseTable.table_type};
        """).fetchall()
        print(value_check_type)
        print('##############################################')
        value_check_subtype = self.cursor.execute(f"""
            SELECT * FROM {DataBaseTable.table_subtype};
        """).fetchall()
        print(value_check_subtype)
        print('##############################################')
        value_check_type_subtype = self.cursor.execute(f"""
            SELECT * FROM {DataBaseTable.table_type_subtype};
        """).fetchall()
        print(value_check_type_subtype)
        print('1111111111111111111111111111111111111111111111111')
        value_check_subtype = self.cursor.execute(f"""
            SELECT * FROM {DataBaseTable.table_subtype_user}
        """).fetchall()
        value_check_type = self.cursor.execute(f"""
            SELECT * FROM {DataBaseTable.table_type_user};
        """).fetchall()
        print(value_check_type)
        print('##############################################')
        print(value_check_subtype)
        print('##############################################')
        value_developed = self.cursor.execute(f"""
            SELECT * FROM {DataBaseTable.table_task};
        """).fetchall()
        print(value_developed)
        print('MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM')
        print(self.cursor.execute(f"SELECT * FROM {DataBaseTable.table_user_settings};").fetchall())
        print('000000000000000000000000000000000000000000000000000000000000000')
